/****************************************************************************
 *  _____       ______  _____
 * |_   _|     |  ____|/ ____|
 *   | |  _ __ | |__  | (___    Institute of Embedded Systems
 *   | | | '_ \|  __|  \___ \   Zürcher Hochschule für Angewandte
 *  _| |_| | | | |____ ____) |  Wissenschaften
 * |_____|_| |_|______|_____/   8401 Winterthur, Switzerland
 *
 ****************************************************************************
 *
 * @version $Rev: 212 $
 * @author  $Author: bacr $
 * @date    $Date: 2014-01-10 14:09:50 +0100 (ven., 10 janv. 2014) $
 *
 ***************************************************************************/

#ifndef __PTP2_PORT_H__
#define __PTP2_PORT_H__

typedef struct ptp2_port_t          ptp2_port_t;
#ifndef __PTP2_MASTER_H__
typedef struct ptp2_master_t        ptp2_master_t;
#endif

#include "object.h"

#include "hcpp/ptp2_task_queue.h"
#include "hcpp/ptp2_node_table.h"
#include "hcpp/ptp2_shadow_table.h"
#include "hcpp/ptp2_types.h"
#include "hcpp/ptp2_datasets.h"

#include "packet/packet.h"

#define PTP2_PORT_MULTICAST_IPV4_PRIMARY_IP_INDEX           0
#define PTP2_PORT_MULTICAST_IPV4_PDELAY_IP_INDEX            1

#define PTP2_PORT_MULTICAST_IPV6_PRIMARY_IP_INDEX           0
#define PTP2_PORT_MULTICAST_IPV6_PDELAY_IP_INDEX            1

#define PTP2_PORT_MULTICAST_IPV4_PRIMARY_MAC_INDEX          0
#define PTP2_PORT_MULTICAST_IPV4_PDELAY_MAC_INDEX           1
#define PTP2_PORT_MULTICAST_ETHER_PRIMARY_MAC_INDEX         2
#define PTP2_PORT_MULTICAST_ETHER_PDELAY_MAC_INDEX          3

struct ptp2_port_t {
    object_t            obj;

    ptp2_port_ds_t      port_ds;

    /* ptp2 master */
    ptp2_master_t      *master;
    ptp2_node_table_t   node_table;
    ptp2_shadow_table_t shadow_table;

    /* task queue */
    ptp2_task_t         task_rx;
    ptp2_task_t         task_process;
    ptp2_task_t         task_tx;
    ptp2_task_t         task_check_ip;
    ptp2_task_t         task_test1; /* test task */
    ptp2_task_t         task_test2; /* test task */

    /* network */
    mac_address_t       mac;
    ipv4_address_t      ipv4;
    ipv4_address_t      ipv4_gateway;
    ipv4_address_t      ipv4_netmask;
    ipv6_address_t      ipv6;
    ptp2_address_type_t multicast_address_type;             /* only in multicast mode (defaultDS.unicastMode = false) */
    ipv4_address_t      multicast_ipv4[PTP2_PORT_MULTICAST_IPV4_COUNT];
    ipv6_address_t      multicast_ipv6[PTP2_PORT_MULTICAST_IPV6_COUNT];
    mac_address_t       multicast_mac[PTP2_PORT_MULTICAST_MAC_COUNT];

    /* packets */
    raw_packet_t        raw_request;
    raw_packet_t        raw_response;
    packet_t            request;
    packet_t            response;

    /* private data (lwIP stuff) */
    uint32_t            data_priv[32];
};

bool ptp2_port_init                         (ptp2_port_t *this, ptp2_master_t *master);
bool ptp2_port_receive                      (ptp2_port_t *this);
bool ptp2_port_transmit                     (ptp2_port_t *this);
void ptp2_port_change_port_state            (ptp2_port_t *this, ptp2_port_state_t new_port_state);
void ptp2_port_multicast_announce_enable    (ptp2_port_t *this);
void ptp2_port_multicast_announce_disable   (ptp2_port_t *this);
void ptp2_port_use_static_ipv4              (ptp2_port_t *this);
void ptp2_port_use_dhcp_ipv4                (ptp2_port_t *this);
void ptp2_port_set_ipv4                     (ptp2_port_t *this, const ipv4_address_t *ipv4);
void ptp2_port_set_ipv4_gateway             (ptp2_port_t *this, const ipv4_address_t *ipv4_gateway);
void ptp2_port_set_ipv4_netmask             (ptp2_port_t *this, const ipv4_address_t *ipv4_netmask);
void ptp2_port_set_ipv6                     (ptp2_port_t *this, const ipv6_address_t *ipv6);
void ptp2_port_set_mac                      (ptp2_port_t *this, const mac_address_t *mac);
void ptp2_port_set_multicast_address_type   (ptp2_port_t *this, const ptp2_address_type_t multicast_address_type);
bool ptp2_port_set_multicast_ipv4           (ptp2_port_t *this, uint8_t index, const ipv4_address_t *ipv4);
bool ptp2_port_set_multicast_ipv4_list      (ptp2_port_t *this, const ipv4_address_t ipv4_list[], uint8_t size);
bool ptp2_port_set_multicast_ipv6           (ptp2_port_t *this, uint8_t index, const ipv6_address_t *ipv6);
bool ptp2_port_set_multicast_ipv6_list      (ptp2_port_t *this, const ipv6_address_t ipv6_list[], uint8_t size);
bool ptp2_port_set_multicast_mac            (ptp2_port_t *this, uint8_t index, const mac_address_t *mac);
bool ptp2_port_set_multicast_mac_list       (ptp2_port_t *this, const mac_address_t mac_list[], uint8_t size);


#endif
